﻿/**
 * \file Combat.cs
 * \brief gere un combat
 * */
namespace Implementation
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using interfaces;


    class Combat
    {
        private UniteImpl att;
        private UniteImpl def;
        private int x;
        private int y;
        private bool isVictoire = false;

        //constructeur
        public Combat(UniteImpl u, int x, int y)
        {
            att = u;
            this.x = x;
            this.y = y;
            bool isUnite = choixDefenseur();

            if (!isUnite)
                victoire();
        }
        
        /**
         * \fn choixDefenseur()
         * \brief choix du défenseur de la case attaquée, à savoir celui qui a la défense la plus élevée
         * \return bool
         */
        private bool choixDefenseur()
        {
            List<Unite> defs = att.getJoueur().getJeu().getUnitePosition(x, y);
            if (defs == null || !defs.Any())
                return false;

            def = (UniteImpl)getDefenseurPlusHaut(defs);
            return true;
        }

        /**
         * \fn getDefenseurPlusHaut(List<Unite> defs)
         * \brief retourne le défenseur qui a la défence la plus élevée
         * \return UniteImpl
         */
        private UniteImpl getDefenseurPlusHaut(List<Unite> defs)
        {
            UniteImpl tmp = (UniteImpl)defs.First();
            foreach (UniteImpl u in defs)
            {
                if (u.getDef() > tmp.getDef())
                    tmp = u;
            }
            return tmp;
        }

        /**
         * \fn faireCombat()
         * \brief gère le combat. Reourne vrai si l'attaquant gagne, faut si il perd
         * \return bool
         */
        public bool faireCombat()
        {
            int pt_vie = att.getVie();
            if(def.getVie() > pt_vie)
                pt_vie = def.getVie();

            Random rand = new Random();
            int r = rand.Next(3, (pt_vie + 2));

            int ptatt = att.getAtt();
            int ptdef = def.getDef();

            for (int i = 0; i < r; i++)
            {
                int pourcentage = getpourcentageVictoire();
                int victoire = rand.Next(0, 100);
                if (victoire > pourcentage)
                    def.baisseVie(1);
                else
                    att.baisseVie(1);

                if (!def.estEnVie() || !att.estEnVie())
                    break;
            }

            if (!def.estEnVie())
            {
                def.getJoueur().getCivilisation().supprUnite(def);
                victoire();
                return true;
            }
            if(!att.estEnVie())
                att.getJoueur().getCivilisation().supprUnite(att);

            return false;
        }

        /**
         * \fn victoire()
         * \brief action en cas de victoire de l'att
         */ 
        private void victoire()
        {
            List<Unite> defunit = att.getJoueur().getJeu().getUnitePosition(x, y);
            Ville defville = att.getJoueur().getJeu().getVillePosition(x, y);
            if (!defunit.Any() && defville == null)
            { att.deplacement(x, y); this.isVictoire = true; }
            else if (!defunit.Any() && defville != null)
            {             
                defville.setJoueur(att.getJoueur());
                att.getJoueur().getCivilisation().addVilles(defville);
                att.getJoueur().getJeu().getEnemie(att.getJoueur()).getCivilisation().supprVilles(defville);
                isVictoire = true;
                att.deplacement(x, y);
            }
            
        }

        public bool isvictoire()
        {
            return isVictoire;
        }

        /**
         * \fn getpourcentageVictoire()
         * \brief donne les pourcentage de chance de l'attaquant de perdre
         * \return int
         */
        private int getpourcentageVictoire()
        {
            int ptatt = att.getAtt();
            int ptdef = def.getDef();

            if (att.getJoueur().getCivilisation().aDirecteur())
            {
                List<Unite> lu = att.getJoueur().getJeu().getUnitePosition(att.getX(), att.getY());
                foreach (Unite u in lu)
                {
                    if (u is Directeur)
                    {
                        ptatt = ptatt + (ptatt / 2);
                        break;
                    }
                }
            }
            if (def.getJoueur().getCivilisation().aDirecteur())
            {
                List<Unite> lu = def.getJoueur().getJeu().getUnitePosition(def.getX(), def.getY());
                foreach (Unite u in lu)
                {
                    if (u is Directeur)
                    {
                        ptdef = ptdef + (ptdef / 2);
                        break;
                    }
                }
            }

            if (ptatt < ptdef)
            {
                int petit = ptatt;
                int grand = ptdef;
                int rapport = 50 + ((1-petit / grand) / 2) * 100;
                return rapport;
            }
            else if (ptatt > ptdef)
            {
                int petit = ptdef;
                int grand = ptatt;
                int rapport = 100 - (50 + ((1 - petit / grand) / 2) * 100);
                return rapport;
            }
            else 
            {
                return 50;
            }
        }

    }
}
